﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Redmine.Core.Entities;
using Redmine.Core.UnitOfWork;
using UnitOfWork;

namespace Redmine.Core.Repositories
{
    public class SettingRepository : RepositoryBase<Setting, DbDataContext>, ISettingRepository
    {
        static SettingRepository()
        {
            FilePath = Environment.CurrentDirectory + "\\Config\\Setting.xml";
            SettingConfig = XElement.Parse(FilePath);
            CachedSettings = new Dictionary<string, string>(100);
        }
        public SettingRepository(IDatabaseFactory<DbDataContext> databaseFactory)
            : base(databaseFactory)
        {

        }
        private readonly static string FilePath;
        private readonly static XElement SettingConfig;
        public XElement GetConfig()
        {
            return SettingConfig;
        }

        /// <summary>
        /// 查找name，没找到时创建一个带默认值的setting
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        private Setting FindOrDefault(string name)
        {
            XElement item = GetConfig().Descendants(name).FirstOrDefault();
            if (item == null)
                throw new ArgumentException("There's no setting named " + name);
            var setting = Find(t => t.Name.Equals(name)).FirstOrDefault();
            if (setting == null)
            {
                setting = new Setting { Name = name };
                var firstOrDefault = item.Descendants("default").FirstOrDefault();
                if (firstOrDefault != null)
                    setting.Value = firstOrDefault.Value;
            }
            return setting;
        }
        private static readonly Dictionary<string, string> CachedSettings;
        /// <summary>
        /// 根据属性name获取value，带缓存。set时同时保存
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public string this[string name]
        {
            get
            {
                string temValue;
                if (!CachedSettings.TryGetValue(name, out temValue))
                {
                    temValue = FindOrDefault(name).Value;
                    CachedSettings.Add(name, temValue);
                }
                return temValue;
            }
        }

        public void RemoveCached(string name)
        {
            CachedSettings.Remove(name);
        }
    }
    public interface ISettingRepository : IRepository<Setting>
    {
        XElement GetConfig();
        string this[string name] { get; }
    }
}
